package cc.unitmesh.devins.idea.toolwindow.codereview

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import cc.unitmesh.agent.codereview.ModifiedCodeRange
import cc.unitmesh.agent.linter.LintFileResult
import cc.unitmesh.agent.linter.LintIssue
import cc.unitmesh.agent.linter.LintSeverity
import cc.unitmesh.devins.idea.compose.IdeaCircularProgressIndicator
import cc.unitmesh.devins.idea.renderer.sketch.IdeaSketchRenderer
import cc.unitmesh.devins.idea.theme.IdeaAutoDevColors
import com.intellij.openapi.Disposable
import org.jetbrains.jewel.foundation.theme.JewelTheme
import org.jetbrains.jewel.ui.Orientation
import org.jetbrains.jewel.ui.component.*

@Composable
internal fun IdeaAIAnalysisPanel(state: CodeReviewState, viewModel: IdeaCodeReviewViewModel, parentDisposable: Disposable, modifier: Modifier = Modifier) {
    val progress = state.aiProgress
    Column(modifier = modifier.background(JewelTheme.globalColors.panelBackground)) {
        IdeaAnalysisHeader(progress.stage, state.diffFiles.isNotEmpty(), { viewModel.startAnalysis() }, { viewModel.cancelAnalysis() })
        Divider(Orientation.Horizontal, modifier = Modifier.fillMaxWidth().height(1.dp))
        state.error?.let { Text(it, style = JewelTheme.defaultTextStyle.copy(color = Color(0xFFEF5350), fontSize = 12.sp), modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp)) }
        Box(modifier = Modifier.fillMaxSize().padding(8.dp)) {
            if (progress.stage == AnalysisStage.IDLE && progress.lintResults.isEmpty()) {
                Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                    Text("Click 'Start Review' to analyze code changes with AI", style = JewelTheme.defaultTextStyle.copy(color = JewelTheme.globalColors.text.info, fontSize = 12.sp))
                }
            } else {
                LazyColumn(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(8.dp)) {
                    if (progress.lintResults.isNotEmpty() || progress.lintOutput.isNotEmpty()) {
                        item { IdeaLintAnalysisCard(progress.lintResults, progress.lintOutput, progress.stage == AnalysisStage.RUNNING_LINT, state.diffFiles, progress.modifiedCodeRanges) }
                    }
                    if (progress.analysisOutput.isNotEmpty()) {
                        item { IdeaAIAnalysisSection(progress.analysisOutput, progress.stage == AnalysisStage.ANALYZING_LINT, parentDisposable) }
                    }
                    if (progress.planOutput.isNotEmpty()) {
                        item { IdeaModificationPlanSection(progress.planOutput, progress.stage == AnalysisStage.GENERATING_PLAN, parentDisposable) }
                    }
                    if (progress.stage == AnalysisStage.WAITING_FOR_USER_INPUT) {
                        item { IdeaUserInputSection({ viewModel.proceedToGenerateFixes() }, { viewModel.cancelAnalysis() }) }
                    }
                    if (progress.fixRenderer != null || progress.stage == AnalysisStage.GENERATING_FIX) {
                        item { IdeaSuggestedFixesSection(progress.fixOutput, progress.stage == AnalysisStage.GENERATING_FIX, parentDisposable) }
                    }
                }
            }
        }
    }
}

@Composable
internal fun IdeaAnalysisHeader(stage: AnalysisStage, hasDiffFiles: Boolean, onStartAnalysis: () -> Unit, onCancelAnalysis: () -> Unit) {
    Row(modifier = Modifier.fillMaxWidth().padding(12.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
        Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
            Text("AI Code Review", style = JewelTheme.defaultTextStyle.copy(fontWeight = FontWeight.Bold, fontSize = 14.sp))
            val (statusText, statusColor) = when (stage) {
                AnalysisStage.IDLE -> "Ready" to JewelTheme.globalColors.text.info
                AnalysisStage.RUNNING_LINT -> "Linting..." to IdeaAutoDevColors.Amber.c400
                AnalysisStage.ANALYZING_LINT -> "Analyzing..." to IdeaAutoDevColors.Blue.c400
                AnalysisStage.GENERATING_PLAN -> "Planning..." to IdeaAutoDevColors.Blue.c400
                AnalysisStage.WAITING_FOR_USER_INPUT -> "Awaiting Input" to IdeaAutoDevColors.Amber.c400
                AnalysisStage.GENERATING_FIX -> "Fixing..." to IdeaAutoDevColors.Indigo.c400
                AnalysisStage.COMPLETED -> "Done" to IdeaAutoDevColors.Green.c400
                AnalysisStage.ERROR -> "Error" to IdeaAutoDevColors.Red.c400
                AnalysisStage.FETCHING_DIFF -> "Fetching Diff..." to IdeaAutoDevColors.Amber.c400
                AnalysisStage.ANALYZING_CHANGES -> "Analyzing Changes..." to IdeaAutoDevColors.Amber.c400
                AnalysisStage.GENERATING_REVIEW -> "Generating Review..." to IdeaAutoDevColors.Amber.c400
            }
            if (stage != AnalysisStage.IDLE) {
                Box(modifier = Modifier.background(statusColor.copy(alpha = 0.15f), RoundedCornerShape(4.dp)).padding(horizontal = 6.dp, vertical = 2.dp)) {
                    Row(horizontalArrangement = Arrangement.spacedBy(4.dp), verticalAlignment = Alignment.CenterVertically) {
                        if (stage != AnalysisStage.COMPLETED && stage != AnalysisStage.ERROR) IdeaCircularProgressIndicator()
                        Text(statusText, style = JewelTheme.defaultTextStyle.copy(color = statusColor, fontSize = 11.sp, fontWeight = FontWeight.Medium))
                    }
                }
            }
        }
        when (stage) {
            AnalysisStage.IDLE, AnalysisStage.COMPLETED, AnalysisStage.ERROR -> DefaultButton(onClick = onStartAnalysis, enabled = hasDiffFiles) { Text("Start Review") }
            else -> OutlinedButton(onClick = onCancelAnalysis) { Text("Cancel") }
        }
    }
}

@Composable
internal fun IdeaLintAnalysisCard(lintResults: List<LintFileResult>, lintOutput: String, isActive: Boolean, diffFiles: List<DiffFileInfo>, modifiedCodeRanges: Map<String, List<ModifiedCodeRange>>) {
    var isExpanded by remember { mutableStateOf(true) }
    val totalErrors = lintResults.sumOf { it.errorCount }
    val totalWarnings = lintResults.sumOf { it.warningCount }
    IdeaCollapsibleCard("Lint Analysis", isExpanded, { isExpanded = it }, isActive, {
        if (totalErrors > 0 || totalWarnings > 0) {
            Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
                if (totalErrors > 0) IdeaBadge("$totalErrors errors", IdeaAutoDevColors.Red.c400)
                if (totalWarnings > 0) IdeaBadge("$totalWarnings warnings", IdeaAutoDevColors.Amber.c400)
            }
        }
    }) {
        Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
            lintResults.forEach { result -> if (result.issues.isNotEmpty()) IdeaLintFileCard(result, modifiedCodeRanges[result.filePath] ?: emptyList()) }
            if (lintOutput.isNotEmpty() && lintResults.isEmpty()) Text(lintOutput, style = JewelTheme.defaultTextStyle.copy(fontFamily = FontFamily.Monospace, fontSize = 11.sp), modifier = Modifier.horizontalScroll(rememberScrollState()))
        }
    }
}

@Composable
private fun IdeaLintFileCard(fileResult: LintFileResult, modifiedRanges: List<ModifiedCodeRange>) {
    Column(modifier = Modifier.fillMaxWidth().background(JewelTheme.globalColors.panelBackground.copy(alpha = 0.5f), RoundedCornerShape(4.dp)).padding(8.dp), verticalArrangement = Arrangement.spacedBy(4.dp)) {
        Text(fileResult.filePath.substringAfterLast("/"), style = JewelTheme.defaultTextStyle.copy(fontWeight = FontWeight.Medium, fontSize = 12.sp))
        fileResult.issues.take(5).forEach { IdeaLintIssueRow(it, modifiedRanges) }
        if (fileResult.issues.size > 5) Text("...and ${fileResult.issues.size - 5} more issues", style = JewelTheme.defaultTextStyle.copy(color = JewelTheme.globalColors.text.info, fontSize = 11.sp))
    }
}

@Composable
private fun IdeaLintIssueRow(issue: LintIssue, modifiedRanges: List<ModifiedCodeRange>) {
    val isInModifiedRange = modifiedRanges.any { issue.line in it.startLine..it.endLine }
    val severityColor = when (issue.severity) { LintSeverity.ERROR -> Color(0xFFEF5350); LintSeverity.WARNING -> Color(0xFFFFC107); LintSeverity.INFO -> Color(0xFF42A5F5) }
    Row(modifier = Modifier.fillMaxWidth().padding(vertical = 2.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.Top) {
        Text("L${issue.line}", style = JewelTheme.defaultTextStyle.copy(fontFamily = FontFamily.Monospace, fontSize = 10.sp, color = if (isInModifiedRange) severityColor else JewelTheme.globalColors.text.info), modifier = Modifier.width(40.dp))
        Column(modifier = Modifier.weight(1f)) {
            Text(issue.message, style = JewelTheme.defaultTextStyle.copy(fontSize = 11.sp))
            issue.rule?.let { Text(it, style = JewelTheme.defaultTextStyle.copy(fontSize = 10.sp, color = JewelTheme.globalColors.text.info)) }
        }
    }
}

@Composable
internal fun IdeaAIAnalysisSection(analysisOutput: String, isActive: Boolean, parentDisposable: Disposable) {
    var isExpanded by remember { mutableStateOf(true) }
    IdeaCollapsibleCard("AI Analysis", isExpanded, { isExpanded = it }, isActive) {
        IdeaSketchRenderer.RenderResponse(
            content = analysisOutput,
            isComplete = !isActive,
            parentDisposable = parentDisposable,
            modifier = Modifier.fillMaxWidth()
        )
    }
}

@Composable
internal fun IdeaModificationPlanSection(planOutput: String, isActive: Boolean, parentDisposable: Disposable) {
    var isExpanded by remember { mutableStateOf(true) }
    IdeaCollapsibleCard("Modification Plan", isExpanded, { isExpanded = it }, isActive, { if (isActive) IdeaBadge("Generating...", IdeaAutoDevColors.Blue.c400) }) {
        IdeaSketchRenderer.RenderResponse(
            content = planOutput,
            isComplete = !isActive,
            parentDisposable = parentDisposable,
            modifier = Modifier.fillMaxWidth()
        )
    }
}

@Composable
internal fun IdeaUserInputSection(onGenerate: (String) -> Unit, onCancel: () -> Unit) {
    var userInput by remember { mutableStateOf(TextFieldValue("")) }
    IdeaCollapsibleCard("Your Feedback", true, {}, true, { IdeaBadge("Action Required", IdeaAutoDevColors.Amber.c400) }) {
        Column(modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(12.dp)) {
            Text("Review the plan above and provide any additional instructions:", style = JewelTheme.defaultTextStyle.copy(fontSize = 12.sp))
            TextArea(value = userInput, onValueChange = { userInput = it }, modifier = Modifier.fillMaxWidth().height(80.dp), placeholder = { Text("Optional: Add specific instructions or constraints...") })
            Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.End)) {
                OutlinedButton(onClick = onCancel) { Text("Cancel") }
                DefaultButton(onClick = { onGenerate(userInput.text) }) { Text("Generate Fixes") }
            }
        }
    }
}

@Composable
internal fun IdeaSuggestedFixesSection(fixOutput: String, isGenerating: Boolean, parentDisposable: Disposable) {
    var isExpanded by remember { mutableStateOf(true) }
    IdeaCollapsibleCard("Fix Generation", isExpanded, { isExpanded = it }, isGenerating, {
        if (isGenerating) {
            Row(horizontalArrangement = Arrangement.spacedBy(4.dp), verticalAlignment = Alignment.CenterVertically) {
                IdeaCircularProgressIndicator()
                IdeaBadge("Generating...", IdeaAutoDevColors.Indigo.c400)
            }
        } else if (fixOutput.isNotEmpty()) IdeaBadge("Complete", IdeaAutoDevColors.Green.c400)
    }) {
        when {
            fixOutput.isNotEmpty() -> IdeaSketchRenderer.RenderResponse(
                content = fixOutput,
                isComplete = !isGenerating,
                parentDisposable = parentDisposable,
                modifier = Modifier.fillMaxWidth()
            )
            isGenerating -> Box(modifier = Modifier.fillMaxWidth().padding(16.dp), contentAlignment = Alignment.Center) { IdeaCircularProgressIndicator() }
            else -> Text("No fixes generated yet.", style = JewelTheme.defaultTextStyle.copy(color = JewelTheme.globalColors.text.info, fontSize = 12.sp))
        }
    }
}

@Composable
internal fun IdeaCollapsibleCard(title: String, isExpanded: Boolean, onExpandChange: (Boolean) -> Unit, isActive: Boolean = false, badge: @Composable (() -> Unit)? = null, content: @Composable () -> Unit) {
    val backgroundColor = if (isActive) IdeaAutoDevColors.Blue.c600.copy(alpha = 0.08f) else JewelTheme.globalColors.panelBackground
    Column(modifier = Modifier.fillMaxWidth().background(backgroundColor, RoundedCornerShape(6.dp))) {
        Row(modifier = Modifier.fillMaxWidth().clickable { onExpandChange(!isExpanded) }.padding(12.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
            Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
                Text(if (isExpanded) "-" else "+", style = JewelTheme.defaultTextStyle.copy(fontWeight = FontWeight.Bold, fontSize = 14.sp))
                Text(title, style = JewelTheme.defaultTextStyle.copy(fontWeight = FontWeight.Bold, fontSize = 13.sp))
                badge?.invoke()
            }
        }
        AnimatedVisibility(visible = isExpanded, enter = expandVertically() + fadeIn(), exit = shrinkVertically() + fadeOut()) {
            Box(modifier = Modifier.fillMaxWidth().padding(start = 12.dp, end = 12.dp, bottom = 12.dp)) { content() }
        }
    }
}

@Composable
internal fun IdeaBadge(text: String, color: Color) {
    Box(modifier = Modifier.background(color.copy(alpha = 0.15f), RoundedCornerShape(4.dp)).padding(horizontal = 6.dp, vertical = 2.dp)) {
        Text(text, style = JewelTheme.defaultTextStyle.copy(color = color, fontSize = 10.sp, fontWeight = FontWeight.Medium))
    }
}
